<template>
  <div class="dial" :class="{ disabled }">
    <svg viewBox="0 0 120 120" class="ring">
      <defs>
        <linearGradient id="g" x1="0" x2="1">
          <stop offset="0%" stop-color="#a8c0ff" />
          <stop offset="100%" stop-color="#3f2b96" />
        </linearGradient>
      </defs>
      <circle
        cx="60"
        cy="60"
        r="46"
        stroke="#f0f3f8"
        stroke-width="8"
        fill="none"
      />
      <path
        :d="arcPath"
        stroke="url(#g)"
        stroke-width="8"
        fill="none"
        stroke-linecap="round"
      />
    </svg>
    <div class="temp">{{ currentTemp }}<span class="unit">℃</span></div>
  </div>
</template>

<script setup>
import { computed } from "vue";

const props = defineProps({
  currentTemp: { type: Number, default: 25 },
  minTemp: { type: Number, default: 16 },
  maxTemp: { type: Number, default: 30 },
  disabled: { type: Boolean, default: false },
});

const progress = computed(() => {
  const span = props.maxTemp - props.minTemp;
  const p = (props.currentTemp - props.minTemp) / span;
  return Math.min(1, Math.max(0, p));
});

const arcPath = computed(() => buildArc(progress.value));

function polarToCartesian(cx, cy, r, angle) {
  const a = ((angle - 90) * Math.PI) / 180.0;
  return {
    x: cx + r * Math.cos(a),
    y: cy + r * Math.sin(a),
  };
}

function buildArc(p) {
  const startAngle = 135;
  const endAngle = 405;
  const angle = startAngle + (endAngle - startAngle) * p;
  const start = polarToCartesian(60, 60, 46, startAngle);
  const end = polarToCartesian(60, 60, 46, angle);
  const largeArc = angle - startAngle <= 180 ? 0 : 1;
  return `M ${start.x} ${start.y} A 46 46 0 ${largeArc} 1 ${end.x} ${end.y}`;
}
</script>

<style scoped>
.dial {
  display: grid;
  place-items: center;
  position: relative;
}
.ring {
  width: 150px;
  height: 150px;
}
.temp {
  position: absolute;
  font-size: 28px;
  font-weight: 600;
  color: #333;
}
.unit {
  font-size: 12px;
  margin-left: 2px;
  color: #666;
}
.dial.disabled {
  opacity: 0.5;
  filter: grayscale(0.2);
}
</style>
